/**
 *  @file
 *  @brief   笛卡尔坐标系基类定义
 *  @author  wanghuan
 *  @date    2024.04.16
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "DataStructure/Common/SGObject.h"
#include "DataStructure/Input/Coordinate/ICoordinate.h"

SG_DATASTRUCTURE_FEM_NAMESPACE_OPEN
/** @brief 直角坐标系
 *
 * 通过三个节点定义坐标系基矢量方向, `m_G1`定义坐标系原点。
 * 矢量`m_G2` - `m_G1` 定义坐标系的Z轴。 `m_G3`确定坐标系XZ平面。
 */
struct DECLSPEC CartesianCoord : public ICoordinate
{
    CartesianCoord ();
    /** 构造函数
     *
     * 传入坐标系Id和 定义坐标系的三个节点编号
     */
    CartesianCoord (SG::DataStructure::Common::Id id,
                    SG::DataStructure::Common::Id GA,
                    SG::DataStructure::Common::Id GB,
                    SG::DataStructure::Common::Id GC);
    virtual ~CartesianCoord () = default;

    /** @brief 查询坐标系状态
     * 当坐标系的三个节点的参考坐标系为0，或者全都已经被初始化， 应返回Status_Ready
     */
    virtual SG::DataStructure::FEM::CoordStatus QueryStatus (ICoordinatePArray& coordSet) const override;

    /** @brief 传入节点的参考坐标系*/
    void SetRefCoordId (std::size_t index, SG::DataStructure::Common::Id refId) override;

    /** @brief 获得定义坐标系的参考点Id*/
    virtual void GetRefPoint (_OUT SG::DataStructure::Common::Id& GA,
                              _OUT SG::DataStructure::Common::Id& GB,
                              _OUT SG::DataStructure::Common::Id& GC) const override;

    /** @brief 获得定义坐标系的参考坐标系和参考点, 为了接口的一致性，不应该被调用*/
    virtual void GetRefPoint (_OUT SG::DataStructure::Common::Id& ref,
                              _OUT SG::Algebra::Point& PA,
                              _OUT SG::Algebra::Point& PB,
                              _OUT SG::Algebra::Point& PC) override;

    virtual SG::Algebra::Point Trans2Basic (const SG::DataStructure::Common::Real& localX,
                                            const SG::DataStructure::Common::Real& localY,
                                            const SG::DataStructure::Common::Real& localZ) const override;

    SG::DataStructure::Common::Id m_G1;      ///< 节点1编号
    SG::DataStructure::Common::Id m_G2;      ///< 节点2编号
    SG::DataStructure::Common::Id m_G3;      ///< 节点3编号
    SG::DataStructure::Common::Id m_ref[3];  /// 三个节点的参考坐标系编号
};

///< @brief 直角坐标系数据结构体，通过节点ID构建。
struct DECLSPEC CORD1RData : public SGObject
{
    SG::DataStructure::Common::Id m_g1 = 0;  /// 代表坐标系原点的节点ID，i, Bi, Ci给出三个点相对于RID定义的坐标系的坐标
    SG::DataStructure::Common::Id m_g2      = 0;  /// 代表坐标系Z轴的节点ID，
    SG::DataStructure::Common::Id m_g3      = 0;  /// 位于X-Z平面的节点ID
    SG::DataStructure::Common::Id m_dominId = 0;  ///

    static SG::DataStructure::FEM::CoordTypes GetType ()
    {
        return SG::DataStructure::FEM::CoordTypes::COORDTYPE_Cartesian;
    };

    CartesianCoord GetCartesianCoord ();
};

/// @brief 判断两个CORD1RData是否相等
/// @param a
/// @param b
/// @return
DECLSPEC bool operator== (const CORD1RData& a, const CORD1RData& b);

SG_DATASTRUCTURE_FEM_NAMESPACE_CLOSE